from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils.translation import gettext_lazy as _
from django.utils import timezone
import uuid
from .utils import generate_homomorphic_token

# 生成UUID令牌
def generate_uuid_token():
    return str(uuid.uuid4())

# 生成唯一令牌，确保在ResaleRecord中不重复
def generate_unique_token():
    new_token = str(uuid.uuid4())
    from .models import ResaleRecord
    while ResaleRecord.objects.filter(new_authorization_token=new_token).exists():
        new_token = str(uuid.uuid4())
    return new_token

class User(AbstractUser):
    """
    自定义用户模型，使用电话号码作为唯一标识
    移除默认的username字段，使用phone_number作为登录标识
    """
    # 移除默认的username字段
    username = None
    id_card = models.CharField(max_length=18, unique=True, verbose_name="身份证号")
    phone_number = models.CharField(max_length=11, unique=True, verbose_name="电话号码")

    # 设置使用电话号码作为认证标识
    USERNAME_FIELD = 'phone_number'
    # 创建用户时不需要额外的必填字段
    REQUIRED_FIELDS = []

    # 关联Django权限系统的组和权限字段
    groups = models.ManyToManyField(
        "auth.Group",
        related_name="app01_users",
        blank=True,
        help_text="用户所属组",
        verbose_name="组",
    )
    user_permissions = models.ManyToManyField(
        "auth.Permission",
        related_name="app01_users",
        blank=True,
        help_text="用户权限",
        verbose_name="权限",
    )

    def __str__(self):
        return self.phone_number

class DataOwnership(models.Model):
    """
    数据所有权模型
    存储用户上传数据的元信息和所有权凭证
    """
    owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='owned_data')
    data_file = models.FileField(upload_to='data_files/')  # 上传的数据文件
    signature = models.TextField(verbose_name='数字签名')  # 文件哈希签名
    token = models.TextField(verbose_name='所有权令牌')  # 数据所有权令牌
    public_key = models.TextField(verbose_name='公钥', null=True, blank=True)  # 同态加密公钥
    private_key = models.TextField(verbose_name='私钥', null=True, blank=True)  # 同态加密私钥
    created_at = models.DateTimeField(auto_now_add=True)  # 创建时间
    is_active = models.BooleanField(default=True)  # 数据状态
    phone_number = models.CharField(max_length=11, default='', verbose_name='电话号码')  # 关联的电话号码

    def __str__(self):
        return f"{self.owner.phone_number}'s data - {self.token[:20]}..."

    def save(self, *args, **kwargs):
        """
        保存前自动生成同态加密令牌和密钥对
        """
        if not self.token:
            token_data = generate_homomorphic_token()
            self.token = token_data['token']
            self.public_key = str(token_data['public_key'])
            self.private_key = str(token_data['private_key'])
        super().save(*args, **kwargs)

class UploadedData(models.Model):
    """
    上传数据的基本信息
    存储数据名称、描述等元信息
    """
    data_name = models.CharField(max_length=255)  # 数据名称
    data_description = models.TextField()  # 数据描述
    token = models.CharField(max_length=255, blank=True, null=True)  # 关联的令牌
    signature = models.CharField(max_length=255, blank=True, null=True)  # 关联的签名
    created_at = models.DateTimeField(auto_now_add=True)  # 创建时间

class AuthorizationToken(models.Model):
    """
    授权令牌模型
    管理数据访问授权和转售权限
    """
    original_token = models.TextField(verbose_name="原始令牌")  # 原始数据令牌
    new_token = models.TextField(verbose_name="生成令牌")  # 新生成的授权令牌
    public_key = models.TextField(verbose_name="公钥", null=True, blank=True)  # 同态加密公钥
    private_key = models.TextField(verbose_name="私钥", null=True, blank=True)  # 同态加密私钥
    permission_percentage = models.PositiveIntegerField(default=100, verbose_name="权限百分比")  # 访问权限百分比
    resale_level = models.PositiveIntegerField(default=3, verbose_name="允许转售级数")  # 允许的转售次数
    valid_days = models.PositiveIntegerField(default=30, verbose_name="有效天数")  # 令牌有效期
    sale_time = models.DateTimeField(default=timezone.now, verbose_name="出售时间")  # 出售时间
    seller = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="卖家")  # 卖家用户
    buyer_phone = models.CharField(max_length=11, null=True, blank=True, verbose_name="买家电话")  # 买家电话号码

    def __str__(self):
        return f"Token-{self.new_token[:20]}..."

    def save(self, *args, **kwargs):
        """
        保存前自动生成同态加密令牌和密钥对
        """
        if not self.new_token:
            token_data = generate_homomorphic_token()
            self.new_token = token_data['token']
            self.public_key = str(token_data['public_key'])
            self.private_key = str(token_data['private_key'])
        super().save(*args, **kwargs)

    class Meta:
        verbose_name = "授权令牌"
        verbose_name_plural = verbose_name

class ResaleRecord(models.Model):
    """
    转售记录模型
    记录每次数据转售的详细信息
    """
    authorization_token = models.ForeignKey(AuthorizationToken, on_delete=models.CASCADE, related_name='resale_records')  # 原始授权令牌
    buyer_phone = models.CharField(max_length=11, verbose_name="买家电话")  # 买家电话号码
    resale_level = models.PositiveIntegerField(verbose_name="转售级数")  # 当前转售级数
    valid_days = models.PositiveIntegerField(verbose_name="规定使用天数")  # 新的有效期
    new_authorization_token = models.TextField(verbose_name="新授权令牌")  # 新生成的授权令牌
    public_key = models.TextField(verbose_name="公钥", null=True, blank=True)  # 同态加密公钥
    private_key = models.TextField(verbose_name="私钥", null=True, blank=True)  # 同态加密私钥
    resale_time = models.DateTimeField(auto_now_add=True, verbose_name="转售时间")  # 转售时间
    permission_percentage = models.PositiveIntegerField(verbose_name="转售后权限百分比", null=True, blank=True)  # 转售后的权限百分比
    buyer = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        verbose_name="买家",
        related_name='purchased_records'
    )  # 买家用户

    def __str__(self):
        return f"Resale of {self.authorization_token.new_token[:20]}... to {self.buyer_phone}"

    def save(self, *args, **kwargs):
        """
        保存前自动生成同态加密令牌和密钥对
        """
        if not self.new_authorization_token:
            token_data = generate_homomorphic_token()
            self.new_authorization_token = token_data['token']
            self.public_key = str(token_data['public_key'])
            self.private_key = str(token_data['private_key'])
        super().save(*args, **kwargs)